using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Publicuse.WebCore.SwaggerExtend
{
    public static class SwaggerExtensions
    {
        /// <summary>
        ///  配置Swagger的配置
        /// </summary>
        /// <param name="service"></param>
        /// <param name="docName"></param>
        /// <param name="docDescription"></param>
        public static void AddSwaggerExt(this IServiceCollection service, string docName, string docDescription)
        {
            service.AddEndpointsApiExplorer();
            service.AddSwaggerGen(option =>
            {
                #region 展示控制注释
                {
                    foreach (var version in typeof(ApiVersions).GetEnumNames())
                    {
                        option.SwaggerDoc(version, new OpenApiInfo()
                        {
                            Title = !string.IsNullOrWhiteSpace(docName) ? docName : $"校园进出管理系统系统Api文档",
                            Version = version,
                            Description = !string.IsNullOrWhiteSpace(docDescription) ? docDescription : $"通用版本的CoreApi版本v1",
                            Contact = new OpenApiContact { Name = !string.IsNullOrWhiteSpace(docName) ? docName : $"校园进出管理系统", Email = "1498799985@qq.com", Url = new Uri("https://www.jianshu.com/p/349e130e40d5") },
                            License = new OpenApiLicense { Name = !string.IsNullOrWhiteSpace(docName) ? docName : $"校园进出管理系统", Url = new Uri("https://www.jianshu.com/p/349e130e40d5") }
                        });
                    }
                    // xml文档绝对路径 
                    var file = Path.Combine(AppContext.BaseDirectory, $"{AppDomain.CurrentDomain.FriendlyName}.xml");
                    // true : 显示控制器层注释
                    option.IncludeXmlComments(file, true);
                    // 对action的名称进行排序，如果有多个，就可以看见效果了。
                    option.OrderActionsBy(o => o.RelativePath);
                }
                #endregion

                #region 支持Swagger传递Token
                {
                    //添加安全定义--配置支持token授权机制
                    option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                    {
                        Description = "请输入token,格式为 Bearer xxxxxxxx（注意中间必须有空格）",
                        Name = "Authorization",
                        In = ParameterLocation.Header,
                        Type = SecuritySchemeType.ApiKey,
                        BearerFormat = "JWT",
                        Scheme = "Bearer"
                    });
                    //添加安全要求
                    option.AddSecurityRequirement(new OpenApiSecurityRequirement
                    {
                        {
                            new OpenApiSecurityScheme
                            {
                                Reference =new OpenApiReference()
                                {
                                    Type = ReferenceType.SecurityScheme,
                                    Id ="Bearer"
                                }
                            },
                            new string[]{ }
                        }
                    });
                }
                #endregion 
            });
        }


        /// <summary>
        /// 使用Swagger中间件
        /// </summary>
        /// <param name="app"></param>
        public static void UseSwaggerExt(this WebApplication app, string docName)
        {
            app.UseSwagger();
            app.UseSwaggerUI(option =>
            {
                foreach (string version in typeof(ApiVersions).GetEnumNames())
                {
                    option.SwaggerEndpoint($"/swagger/{version}/swagger.json", string.IsNullOrWhiteSpace(docName) ? docName : $"校园进出管理系统Api文档【{version}】版本");
                }
            });
        }
    }
}
